﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Multiprocessing.Core.Mathematics.Matrices
{
    public abstract class MatrixPart : IMatrixPart
    {
        #region Fields

        private IList<double> _values;

        #endregion

        #region Constructors

        protected MatrixPart(IMatrix matrix, int index)
        {
            if (object.ReferenceEquals(matrix, null))
            {
                throw new ArgumentNullException("matrix");
            }
            Parent = matrix;
            Index = index;
            Fill();
        }

        #endregion

        #region Properties

        public int Index { get; set; }

        public IMatrix Parent { get; private set; }
        
        #endregion

        #region Methods

        public IEnumerator<double> GetEnumerator()
        {
            return _values.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        private void Fill()
        {
            _values = new List<double>(GetElements(Parent, Index));
        }

        protected abstract IEnumerable<double> GetElements(IMatrix matrix, int index);

        public virtual double GetValue(int index)
        {
            return _values[index];
        }

        public virtual void SetValue(int index, double value)
        {
            _values[index] = value;
        }

        #endregion

        public virtual double this[int index]
        {
            get { return GetValue(index); }
            set { SetValue(index, value); }
        }
    }
}
